﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Common.Utilities;

namespace Workflows.Components.TextMining.Collapse
{
    /// <summary>
    /// 
    /// </summary>
    public class OrganizationNameIndexer:IFieldIndexer
    {
        #region members
        private Dictionary<string,string> _SynonymDictionary;
        /// <summary>full name -> synonyms</summary>
        public Dictionary<string,string> SynonymDictionary
        {
            get
            {
                return this._SynonymDictionary;
            }
            set
            {
                this._SynonymDictionary = value;
            }
        }

        private List<string> _StopWords;
        /// <summary></summary>
        public List<string> StopWords
        {
            get
            {
                return this._StopWords;
            }
            set
            {
                this._StopWords = value;
            }
        }

        private Dictionary<string, int> _Words;
        private Dictionary<string, int> _Abbreviations;
        #endregion

        /// <summary>
        /// 
        /// </summary>
        public OrganizationNameIndexer()
        {
            this._Words = new Dictionary<string, int>();
            this._Abbreviations = new Dictionary<string, int>();

            this._SynonymDictionary = new Dictionary<string, string>();
            // university 
            {
                string fullName1 = "university";
                List<string> synonyms1 = new List<string>();
                synonyms1.Add("university");
                synonyms1.Add("univesity");
                synonyms1.Add("universty");
                synonyms1.Add("universit");
                synonyms1.Add("univ");
                synonyms1.Add("univ.");
                synonyms1.Add("u.");
                foreach (string synonym in synonyms1)
                    this._SynonymDictionary.Add(synonym, fullName1);
            }
            // institute
            {
                string fullName2 = "institute";
                List<string> synonyms2 = new List<string>();
                synonyms2.Add("institute");
                synonyms2.Add("inst");
                synonyms2.Add("inst.");
                synonyms2.Add("institution");
                foreach (string synonym in synonyms2)
                    this._SynonymDictionary.Add(synonym, fullName2);
            }
            // school 
            {
                string fullName = "school";
                List<string> synonyms = new List<string>();
                synonyms.Add("school");
                synonyms.Add("sch");
                synonyms.Add("sch.");
                foreach (string synonym in synonyms)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            // college 
            {
                string fullName = "college";
                List<string> synonyms = new List<string>();
                synonyms.Add("college");
                synonyms.Add("coll");
                synonyms.Add("coll.");
                synonyms.Add("col");
                synonyms.Add("col.");
                foreach (string synonym in synonyms)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            // society 
            {
                string fullName = "society";
                List<string> synonyms = new List<string>();
                synonyms.Add("society");
                synonyms.Add("soc");
                synonyms.Add("soc.");
                foreach (string synonym in synonyms)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            // center 
            {
                string fullName = "center";
                List<string> synonyms = new List<string>();
                synonyms.Add("center");
                synonyms.Add("ctr");
                synonyms.Add("ctr.");
                synonyms.Add("ct.");
                synonyms.Add("ct");
                foreach (string synonym in synonyms)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            // health 
            {
                string fullName = "health";
                List<string> synonyms = new List<string>();
                synonyms.Add("health");
                synonyms.Add("hlth");
                synonyms.Add("hlth.");
                foreach (string synonym in synonyms)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            // science 
            {
                string fullName = "science";
                List<string> synonyms = new List<string>();
                synonyms.Add("science");
                synonyms.Add("sci");
                synonyms.Add("sci.");
                foreach (string synonym in synonyms)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            // medical/medicine 
            {
                string fullName = "medicine";
                List<string> synonyms = new List<string>();
                synonyms.Add("medical");
                synonyms.Add("med");
                synonyms.Add("med.");
                synonyms.Add("medicine");
                foreach (string synonym in synonyms)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            // company 
            {
                string fullName3 = "inc";
                List<string> synonyms3 = new List<string>();
                synonyms3.Add("inc");
                synonyms3.Add("inc.");
                synonyms3.Add("incorporated.");
                synonyms3.Add("llc");
                synonyms3.Add("llc.");
                synonyms3.Add("co.");
                synonyms3.Add("co");
                synonyms3.Add("corp");
                synonyms3.Add("corp.");
                foreach (string synonym in synonyms3)
                    this._SynonymDictionary.Add(synonym, fullName3);
            }
            // foundation 
            {
                string fullName = "foundation";
                List<string> synonyms4 = new List<string>();
                synonyms4.Add("foundation");
                synonyms4.Add("fdn");
                synonyms4.Add("fdn.");
                foreach (string synonym in synonyms4)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            // and 
            {
                string fullName = "and";
                List<string> synonyms = new List<string>();
                synonyms.Add("and");
                synonyms.Add("&");
                foreach (string synonym in synonyms)
                    this._SynonymDictionary.Add(synonym, fullName);
            }
            this._StopWords = new List<string>();
            this._StopWords.Add("the");
            this._StopWords.Add(",");
            this._StopWords.Add("of");
            this._StopWords.Add("for");
            this._StopWords.Add("-");
            this._StopWords.Add(".");
            this._StopWords.Add("at");
            this._StopWords.Add("a");
            this._StopWords.Add("an");
            this._StopWords.Add("\\");
            this._StopWords.Add("/");
            this._StopWords.Add("@");
            this._StopWords.Add("#");
            this._StopWords.Add("_");
            this._StopWords.Add("'");
            this._StopWords.Add(":");
            this._StopWords.Add(";");
        }

        #region Implementation of IFieldIndexer

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="fieldValue"></param>
        /// <param name="invertedIndexes"></param>
        public void IndexValue(int key, object fieldValue, ref Dictionary<int, List<int>> invertedIndexes)
        {
            if(fieldValue==null || fieldValue==DBNull.Value)
                return;
            string orgName = fieldValue.ToString().Trim();
            if(orgName.Length==0)
                return;

            string[] words1 = StringUtil.Split(orgName.ToLower(), " ");
            List<string> wordList = new List<string>();
            foreach (string word in words1)
            {
                if (!string.IsNullOrEmpty(word) &&
                    !this._StopWords.Contains(word) && 
                    !this._SynonymDictionary.ContainsKey(word))
                {
                    if (this._SynonymDictionary.ContainsKey(word))
                        wordList.Add(this._SynonymDictionary[word]);
                    else
                        wordList.Add(word);
                }
            }
            foreach(string word in wordList)
            {
                int idx = this._Words.Count;
                if (this._Words.ContainsKey(word))
                    idx = this._Words[word];
                else 
                    this._Words.Add(word, idx);
                if(invertedIndexes.ContainsKey(idx))
                {
                    List<int> keys = invertedIndexes[idx];
                    if(!keys.Contains(key))
                        keys.Add(key);
                    invertedIndexes[idx] = keys;
                }
                else
                {
                    List<int> keys=new List<int>();
                    keys.Add(key);
                    invertedIndexes.Add(idx, keys);
                }
            }
        }

        #endregion
    }
}
